home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / grafik / bildanzeiger / egsflick / eflick.c next >
C/C++ Source or Header  |  1995-03-09  |  20KB  |  787 lines

  1.  
  2. /*
  3.             EGSFlick - Play .FLI/.FLC animations under EGS
  4.                 Frank Neumann, November 1993
  5.  
  6.             This program plays .FLI (fixed to 320x200) or .FLC (any
  7.             resolution) anim files in an EGS window on a graphic board
  8.             that is capable of producing an 8 bit, CLUT-based chunky pixel
  9.             display. This is true for most currently available Amiga graphic
  10.             boards, such as the Rainbow III, Piccolo, Spectrum and maybe
  11.             others that are still to come.
  12.  
  13.             History:
  14.             V1.0 24.03.1993  First version, already stable, but not to
  15.                              be released for a long time.
  16.  
  17.             V1.1 14.11.1993  Thought it would be a good idea to release this
  18.                              goodie - as EGS seems to become more and more
  19.                              used around the world. First release.
  20.             V1.1a 19.11.1993 Removed the Map->Type test of the EScreen - seems
  21.                              I have not yet understood some of EGS' concepts..
  22.  
  23.             V1.2  13.09.1994 After a long break, a small addition: Now listens
  24.                              to the environment variable 'EGSFLICK' which 
  25.                              determines another screen mode than the default.
  26.  
  27.             This code is mostly based on xflick for X11 systems. What follows is
  28.             the original comment:
  29.  
  30.                xflick - Ron Schnell, March, 1991
  31.  
  32.            This code is provided as is, with no warrantees, expressed
  33.                or implied.  I believe this code to be free of encumbrance,
  34.            and offer it to the public domain.  I ask, however, that
  35.            this paragraph and my name be retained in any modified
  36.            versions of the file you may make, and that you notify me
  37.            of any improvements you make to the code.
  38.  
  39.            Ron Schnell (ronnie@sos.com)
  40.  
  41.             The following changes are from Michael Pall
  42.             (pall@rz.uni-karlsruhe.de) Mar 25-28 1991:
  43.  
  44.             Lots of bugfixes and changes to the structure of the files.
  45.             The file is interpreted before we display it.
  46.             Moved the interpretation part to read.c.
  47.             We use Pixmaps and/or XImages.
  48.             Added interactive input to change the speed/single step.
  49.  
  50.             The following extensions are from Klaus Ehrenfried
  51.             (klaus@spock.es.go.dlr.de) Oct 23-24 1992:
  52.  
  53.             Add handling of FLI_DELTA and FLI_256_COLOR chunks.
  54.             Recognize magic number FLC_MAGIC = 0xaf12 for newer
  55.             flic files.
  56. */
  57.  
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include <string.h>
  61. #include <sys/types.h>
  62. #include <sys/signal.h>
  63. #include <sys/time.h>
  64. #include "eflick.h"
  65.  
  66. #include <exec/types.h>
  67. #include <clib/exec_protos.h>
  68. #include <egs/egsintui.h>
  69. #include <egs/clib/egsintui_protos.h>
  70. #include <egs/egsgfx.h>
  71. #include <egs/clib/egsgfx_protos.h>
  72. #include <egs/egs.h>
  73. #include <egs/clib/egs_protos.h>
  74.  
  75. /* Amiga version identification */
  76. static char *version = "$VER: EGSFlick 1.2 (13.09.94)";
  77.  
  78. int verbose = 0;
  79. static int jiffies;
  80.  
  81. /* pointers to required libraries */
  82. struct Library *EGSIntuiBase = NULL;
  83. struct Library *EGSBase = NULL;
  84. struct Library *EGSGfxBase = NULL;
  85. struct Library *EGSBlitBase = NULL;
  86.  
  87. struct EI_NewScreen newscreen = {
  88.  NULL,                     /* screenmode name is put here later... */
  89.  8, 0, "EGSFlick Screen",  /* depth, pad, title */
  90.  NULL,                     /* CLUPtr */
  91.  { 3, 1, 0, 2, 1, 3, 1 },  /* WinColors */
  92.  0,                        /* backPen */
  93.  NULL,                     /* backPattern */
  94.  NULL,                     /* Maus */
  95.  NULL                      /* TextAttr */
  96. };
  97.  
  98.  
  99. static struct EI_NewWindow newWindow =
  100. {
  101.     50, 30, 10, 10, /* LeftEdge, TopEdge, Width, Height */
  102.     0, 0, 0, 0,        /* MinWidth,MinHeight, MaxWidth, MaxHeight */
  103.     NULL,            /* Screen - might be set to some screen later */
  104.     EI_WINDOWCLOSE | EI_WINDOWBACK | EI_WINDOWDRAG,    /* SysGadgets */
  105.     NULL,            /* FirstGadgets */
  106.     "EGSFlick V1.2 by Franky",        /* Title */
  107.     EI_SMART_REFRESH | EI_GIMMEZEROZERO | EI_WINDOWACTIVE,    /* Flags */
  108.     EI_iCLOSEWINDOW | EI_iVANILLAKEY | EI_iACTIVEWINDOW | EI_iINACTIVEWINDOW,    /*EI_IDCMPFlags */
  109.     NULL,            /*Port */
  110.     {0,0,0,0,0,0,0},    /* Colors */
  111.     NULL,                /* Menu */
  112.     NULL                /* Render */
  113. };
  114.  
  115. EI_ScreenPtr screen = NULL;
  116. EI_WindowPtr window = NULL;
  117. E_EBitMapPtr map = NULL;
  118. EG_RastPortPtr rp;
  119. E_CLU oldscreencolors[MAXCOL], screencolors[MAXCOL];
  120.  
  121. static flag_noint = 0;        /* Don't interpret file first */
  122.  
  123. static int fdelay;        /* Frame delay */
  124. static int wwidth, wheight;    /* Width and height of the window */
  125.  
  126. char fliname[256];
  127.  
  128. /* a modified XColor structure definition */
  129. typedef struct {
  130.     unsigned long pixel;
  131.     unsigned char red, green, blue;
  132. } XColor;
  133.  
  134.  
  135. /* The structure to hold the elements of the interpreted display list */
  136.  
  137. struct disp_list
  138. {
  139.     int disp_type;
  140.     int disp_frame;
  141.     E_EBitMapPtr disp_pix;
  142.     XColor *disp_cols;
  143.     int disp_numcol;
  144.     int disp_width, disp_height;
  145.     int disp_destx, disp_desty;
  146.     struct disp_list *disp_next;
  147. };
  148.  
  149. static struct disp_list disp_root;    /* The start of the display list */
  150. static struct disp_list *disp_cur;    /* The current position */
  151.  
  152. extern void interpret_fli();
  153.  
  154. /* prototypes */
  155. void Crash( char * );
  156.  
  157.  
  158. /* Convert the frame delay to microseconds/seconds */
  159. static void
  160. convert_fdelay()
  161. {
  162.     jiffies = (fdelay * 70) / 50;
  163.  
  164. }
  165.  
  166.  
  167. /* Print a usage message and exit */
  168. static void
  169. usage()
  170. {
  171.     (void) fprintf(stderr,
  172.     "Usage: EGSFlick [-v] [-r<count>] [-d<delay>] [-n] fli_file\n");
  173.     (void) fprintf(stderr, " -v Verbose Debugging info\n\
  174.  -r<count>  Repeat count times (0 = loop forever)\n\
  175.  -d<delay>  Delay between frames in 1/70s\n\
  176.  -n         Don't interpret file before display \
  177. (slower but uses less memory)\n");
  178.     exit(0);
  179. }
  180.  
  181.  
  182. /* Check for pending EI_iVANILLAKEY messages and process them */
  183. static void
  184. check_key()
  185. {
  186.     struct EI_EIntuiMsg *msg;
  187.  
  188.     static int stepflag = 0;    /* Default: singlestep is off */
  189.  
  190.     int onestep = stepflag;        /* 1 if we should be loop waiting for a step */
  191.  
  192.     while (NULL != (msg = (struct EI_EIntuiMsg *)GetMsg(window->UserPort)) || onestep)
  193.     {
  194.         if (msg != NULL)
  195.         {
  196.             switch (msg->Class)
  197.             {
  198.                 case EI_iVANILLAKEY:
  199.                     switch (msg->Code)
  200.                     {
  201.                         /* Minus: Slow down */
  202.                         case '-':
  203.                             fdelay++;
  204.                             convert_fdelay();
  205.                             break;
  206.  
  207.                         /* Plus: Speed up */
  208.                         case '+':
  209.                             if (fdelay)
  210.                                 fdelay--;
  211.                             convert_fdelay();
  212.                             break;
  213.  
  214.                         /* Space: Single step */
  215.                         case ' ':
  216.                             stepflag = 1;
  217.                             onestep = 0;
  218.                             break;
  219.  
  220.                         /* c: Continue animation */
  221.                         case 'c':
  222.                             stepflag = 0;
  223.                             onestep = 0;
  224.                             break;
  225.  
  226.                         /* 'q': Quit */
  227.                         case 'q':
  228.                             ReplyMsg(msg);
  229.                             Crash(NULL);
  230.                             break;
  231.                     }
  232.                     break;
  233.  
  234.                 case EI_iCLOSEWINDOW:
  235.                     ReplyMsg(msg);
  236.                     Crash(NULL);
  237.                     break;
  238.  
  239.                 case EI_iACTIVEWINDOW:
  240.                     E_SetRGB8CM(window->WScreen->EScreen, screencolors, 0, MAXCOL);
  241.                     break;
  242.  
  243.                 case EI_iINACTIVEWINDOW:
  244.                     E_SetRGB8CM(window->WScreen->EScreen, oldscreencolors, 0, MAXCOL);
  245.                     break;
  246.  
  247.                 default:
  248.                     printf("You don't really ever want to see this.\n");
  249.                     break;
  250.             }
  251.             ReplyMsg((struct Message *)msg);
  252.         }
  253.     }
  254. }
  255.  
  256.  
  257.  
  258. /* Function to display the interpretation immediately */
  259.  
  260. static void
  261. func_disp(ftype, frame, buf, srcx, srcy, destx, desty, swidth, sheight)
  262. int ftype;
  263. int frame;
  264. unsigned char *buf;
  265. int srcx, srcy;
  266. int destx, desty;
  267. int swidth, sheight;
  268. {
  269.     static int colchange=0;        /* Colormap has changed */
  270.  
  271.     switch (ftype)
  272.     {
  273.         case FLI_COPY:
  274.         case FLI_LC:
  275.         case FLI_DELTA:
  276.         case FLI_BRUN:
  277.             EG_CopyBitMapRastPort(map, rp, srcx, srcy, swidth, sheight, destx, desty);
  278.             break;
  279.  
  280.         case FLI_BLACK:
  281.               EG_SetAPen(rp, 0x00000000);
  282.             EG_RectFill(rp, destx, desty, swidth, sheight);
  283.             break;
  284.  
  285.         case FLI_COLOR:
  286.             while(srcy--)
  287.             {
  288.                 screencolors[srcx].Red   = ((*(buf++) & 0x3f) << 2);
  289.                 screencolors[srcx].Green = ((*(buf++) & 0x3f) << 2);
  290.                 screencolors[srcx].Blue  = ((*(buf++) & 0x3f) << 2);
  291.                 srcx++;
  292.             }
  293.             colchange = 1;
  294.             break;
  295.  
  296.         case FLI_256_COLOR:
  297.             while(srcy--)
  298.             {
  299.                 screencolors[srcx].Red   = ((*(buf++) & 0xff));
  300.                 screencolors[srcx].Green = ((*(buf++) & 0xff));
  301.                 screencolors[srcx].Blue  = ((*(buf++) & 0xff));
  302.                 srcx++;
  303.             }
  304.             colchange = 1;
  305.             break;
  306.  
  307.         case FLI_SYNC:
  308.             if (colchange)
  309.             {
  310.                 E_SetRGB8CM(window->WScreen->EScreen, screencolors, 0, MAXCOL);
  311.                 colchange = 0;
  312.             }
  313.  
  314.             check_key();
  315.  
  316.             /* Do we have a delay between the frames? */
  317.                if (jiffies)
  318.                    Delay(jiffies);
  319.  
  320.             break;
  321.     }
  322. }
  323.  
  324.  
  325.  
  326. /* Store the interpretation */
  327.  
  328. static void
  329. func_interp(ftype, frame, buf, srcx, srcy, destx, desty, swidth, sheight)
  330. int ftype;        /* The type of this chunk */
  331. int frame;        /* The number of this frame */
  332. unsigned char *buf;    /* A pointer to the pixel/colormap data */
  333. int srcx, srcy;        /* The upper left corner in the data array */
  334. int destx, desty;    /* The upper left corner in the window */
  335. int swidth, sheight;    /* The dimensions of the rectangle */
  336. {
  337.     XColor *coltmp;    /* Temporary storage for pointer to XColor struct */
  338.  
  339.     /* set title of EGS window to current frame number */
  340.     char framenum[20];
  341.     sprintf(framenum, "load: frame %d", disp_cur->disp_frame);
  342.     EI_SetWindowTitles(window, framenum, (char *)-1);
  343.  
  344.     /* Allocate another element in the display list */
  345.     disp_cur->disp_next = (struct disp_list *)malloc(sizeof(struct disp_list));
  346.     disp_cur = disp_cur->disp_next;
  347.  
  348.     /* Clear the pointer to the next element so we find the end of the list */
  349.     disp_cur->disp_next = (struct disp_list *)0;
  350.  
  351.     /* Copy info pertaining to all or most of the chunks */
  352.     disp_cur->disp_type = ftype;
  353.     disp_cur->disp_frame = frame;
  354.     disp_cur->disp_width = swidth;
  355.     disp_cur->disp_height = sheight;
  356.     disp_cur->disp_destx = destx;
  357.     disp_cur->disp_desty = desty;
  358.     disp_cur->disp_pix = (E_EBitMapPtr)NULL;
  359.  
  360.     switch (ftype)
  361.     {
  362.         case FLI_COPY:
  363.         case FLI_LC:
  364.         case FLI_DELTA:
  365.         case FLI_BRUN:
  366.             disp_cur->disp_pix = E_AllocBitMap(wwidth, wheight, 8, E_PIXELMAP, 0, 0);
  367.             if (disp_cur->disp_pix == NULL)
  368.                 Crash("could not allocate memory for picture");
  369.             disp_cur->disp_pix->Lock++;
  370.  
  371.             EB_CopyBitMap(map, disp_cur->disp_pix, srcx, srcy, swidth, sheight, 0, 0, 0);
  372.             break;
  373.  
  374.         case FLI_COLOR:
  375.             /* Create an array of XColor to hold the colors. Specific to FLI_COLOR:
  376.                srcx is the starting color index and srcy is the number of colors */
  377.  
  378.             coltmp = (XColor *)malloc(srcy * sizeof(XColor));
  379.             disp_cur->disp_cols = coltmp;
  380.             disp_cur->disp_numcol = srcy;
  381.  
  382.             /* Copy the changed colors to the XColor array */
  383.             while(srcy--)
  384.             {
  385.                 coltmp->red = ((*(buf++) & 0x3f) << 2);
  386.                 coltmp->green = ((*(buf++) & 0x3f) << 2);
  387.                 coltmp->blue = ((*(buf++) & 0x3f) << 2);
  388.                 coltmp->pixel = srcx++;
  389.                 coltmp++;
  390.             }
  391.             break;
  392.  
  393.         case FLI_256_COLOR:
  394.             /* Create an array of XColor to hold the colors. Specific to FLI_256_COLOR:
  395.                srcx is the starting color index and srcy is the number of colors */
  396.             coltmp =  (XColor *)malloc(srcy * sizeof(XColor));
  397.             disp_cur->disp_cols = coltmp;
  398.             disp_cur->disp_numcol = srcy;
  399.  
  400.             /* Copy the changed colors to the XColor array */
  401.             while(srcy--)
  402.             {
  403.                 coltmp->red = ((*(buf++) & 0xff));
  404.                 coltmp->green = ((*(buf++) & 0xff));
  405.                 coltmp->blue = ((*(buf++) & 0xff));
  406.                 coltmp->pixel = srcx++;
  407.                 coltmp++;
  408.             }
  409.             break;
  410.  
  411.         /* FLI_BLACK and FLI_SYNC only need to be stored */
  412.         case FLI_BLACK:
  413.         case FLI_SYNC:
  414.             break;
  415.     }
  416.  
  417. }
  418.  
  419.  
  420. /* Display the stored interpretation */
  421.  
  422. static void
  423. display_interp(dc)
  424. struct disp_list *dc;    /* The structure holding the info on the chunk */
  425. {
  426.     static int colchange=0;    /* Colormap has changed */
  427.     int idx, pixel, numcols;
  428.     int swidth, sheight;    /* Dimension of the changing rectangle */
  429.     int destx, desty;        /* Upper left corner of the rectangle */
  430.  
  431.     /* Copy some fields from the structure */
  432.     swidth = dc->disp_width;
  433.     sheight = dc->disp_height;
  434.     destx = dc->disp_destx;
  435.     desty = dc->disp_desty;
  436.  
  437.     switch (dc->disp_type)
  438.     {
  439.         case FLI_COPY:
  440.         case FLI_LC:
  441.         case FLI_DELTA:
  442.         case FLI_BRUN:
  443.             EG_CopyBitMapRastPort(dc->disp_pix, rp, 0, 0, swidth, sheight, destx, desty);
  444.             break;
  445.  
  446.         case FLI_BLACK:
  447.             /* Clear the whole rectangle */
  448.             EG_SetAPen(rp, 0x00000000);
  449.             EG_RectFill(rp, destx, desty, swidth, sheight);
  450.             break;
  451.  
  452.         case FLI_COLOR:
  453.         case FLI_256_COLOR:
  454.             /* Store the changed colors in the colormap and note that */
  455.             idx = 0;
  456.             numcols = dc->disp_numcol;
  457.             while(numcols--)
  458.             {
  459.                 pixel = dc->disp_cols[idx].pixel;
  460.                 screencolors[pixel].Red   = dc->disp_cols[idx].red;
  461.                 screencolors[pixel].Green = dc->disp_cols[idx].green;
  462.                 screencolors[pixel].Blue  = dc->disp_cols[idx].blue;
  463.                 idx++;
  464.             }
  465.             colchange = 1;
  466.             break;
  467.  
  468.         case FLI_SYNC:
  469.             /* If the colors have changed we set the colormap for the window */
  470.             if (colchange)
  471.             {
  472.                 E_SetRGB8CM(window->WScreen->EScreen, screencolors, 0, MAXCOL);
  473.                 colchange = 0;
  474.             }
  475.  
  476.             check_key();
  477.  
  478.                if (jiffies)
  479.                    Delay(jiffies);
  480.  
  481.             break;
  482.     }
  483. }
  484.  
  485.  
  486. /* Draw a given string to the center of the window */
  487.  
  488. static void
  489. text_center(str)
  490. char *str;
  491. {
  492.     int w;
  493.  
  494.     EG_SetAPen(rp, 0x00000000);
  495.     EG_RectFill(rp, 0, 0, wwidth, wheight);
  496.  
  497.     /* Determine the width of the string */
  498.     w = EG_TextLength(rp, str, strlen(str));
  499.     if (w > wwidth)
  500.         w = wwidth;
  501.  
  502.     /* And draw the string */
  503.     EG_SetAPen(rp, 0xffffff00);
  504.     EG_Move(rp, (wwidth-w)/2, wheight/2);
  505.     EG_Text(rp, str, strlen(str));
  506. }
  507.  
  508.  
  509. main(argc, argv)
  510. int argc;
  511. char *argv[];
  512. {
  513.     int fd;            /* For the main file descriptor */
  514.     struct fli_header header;    /* To hold the main header */
  515.     unsigned char *data;    /* Always has the current image data */
  516.     int repeatcount;        /* How many times to loop */
  517.     unsigned char notfirst;    /* Is this not the first time through? */
  518.     char *fname;        /* Pointer to filename */
  519.     int depth;          /* depth of (EGS default) screen */
  520.     unsigned char *mode; /* for env.-variable */
  521.  
  522.     fdelay = -1;
  523.     repeatcount = 10;
  524.  
  525.     /* required very early for (possible) error handling */
  526.     disp_root.disp_next = (struct disp_list *)0;
  527.  
  528.     while (--argc && argv[1][0] == '-')
  529.     {
  530.         argv++;
  531.         switch (argv[0][1])
  532.         {
  533.             case 'r':
  534.                 repeatcount = atol(&(argv[0][2]));
  535.                 break;
  536.             case 'd':
  537.                 fdelay = atol(&(argv[0][2]));
  538.                 break;
  539.             case 'n':
  540.                 flag_noint = 1;
  541.                 break;
  542.             case 'v':
  543.                 verbose = 1;
  544.                 break;
  545.             default:
  546.                 usage();
  547.         }
  548.  
  549.     }
  550.  
  551.     if (argc != 1)
  552.         usage();
  553.  
  554.     fname = argv[1];
  555.     strcpy(fliname, argv[1]);
  556.  
  557.     fd = open(fname, 0);
  558.     if (fd < 0)
  559.     {
  560.         (void) fprintf(stderr, "Error opening %s.\n", fname);
  561.         perror("EGSFlick");
  562.         exit(1);
  563.     }
  564.  
  565.     /* Read the main FLI header */
  566.     read_flihead(fd, &header);
  567.  
  568.     if (((header.fhd_magic & 0x0000ffff) != FLI_MAGIC) &&
  569.         ((header.fhd_magic & 0x0000ffff) != FLC_MAGIC))
  570.     {
  571.         (void) fprintf(stderr, "%s, not a .fli file.\n", fname);
  572.         exit(0);
  573.     }
  574.  
  575.     /* Get the width and height */
  576.  
  577.     wwidth = header.fhd_width;
  578.     wheight = header.fhd_height;
  579.  
  580.     /* The speed is stored in 1/70 seconds, convert to usecs */
  581.     if (fdelay < 0)
  582.         fdelay = header.fhd_speed;
  583.  
  584.     convert_fdelay();
  585.  
  586.     /* open the required EGS libraries */
  587.     EGSBase = OpenLibrary("egs.library", 0);
  588.     if (NULL == EGSBase)
  589.         Crash ("couldn't open 'egs.library' -- stop.");
  590.  
  591.     EGSBlitBase = OpenLibrary("egsblit.library", 0);
  592.     if (NULL == EGSBlitBase)
  593.         Crash ("couldn't open 'egsblit.library' -- stop.");
  594.  
  595.     EGSIntuiBase = OpenLibrary("egsintui.library", 0);
  596.     if (NULL == EGSIntuiBase)
  597.         Crash ("couldn't open 'egsintui.library' -- stop.");
  598.  
  599.     EGSGfxBase = OpenLibrary("egsgfx.library", 0);
  600.     if (NULL == EGSGfxBase)
  601.         Crash ("couldn't open 'egsgfx.library' -- stop.");
  602.  
  603.     /* 
  604.         try to read environment variable 'EGSFLICK' - if set, use its
  605.         value as the screen mode name and force the window to open
  606.         on that screen instead of the EGS default screen
  607.     */
  608.     mode = getenv("EGSFLICK");
  609.     if (mode != NULL)
  610.     {
  611.         /* EGSFLICK = "default" ?  */
  612.         if (stricmp(mode, "default") != 0)
  613.         {
  614.             newscreen.Mode = mode;
  615.             screen = EI_OpenScreen(&newscreen);
  616.             if (screen == NULL)
  617.                 Crash("Could not open EI_Screen");
  618.             newWindow.Screen = screen;
  619.         }
  620.     }
  621.  
  622.     /*
  623.         open EGS window on the default screen, hoping that it's currently set
  624.         to 8 bit
  625.     */
  626.  
  627.     /* Create a wwidth x wheight window to show the flick */
  628.     newWindow.Width = wwidth;
  629.     newWindow.Height = wheight;
  630.     window = EI_OpenWindow(&newWindow);
  631.     if (window == NULL)
  632.         Crash("Couldn't open EGS window -- stop.");
  633.  
  634.     /* save current color table */
  635.     E_GetRGB8CM(window->WScreen->EScreen, oldscreencolors, 0, MAXCOL);
  636.     E_GetRGB8CM(window->WScreen->EScreen, screencolors, 0, MAXCOL);
  637.  
  638.     /* check if the EGS default screen is really an 8 bit screen - if not, exit */
  639.     depth = window->WScreen->EScreen->Map->Depth;
  640.  
  641. #if 0
  642.     /* This is the 'old' test - doesn't work on a Spectrum, however, so I removed it for now.. */
  643.     if ((window->WScreen->EScreen->Map->Depth != 8) ||
  644.         (window->WScreen->EScreen->Map->Type != E_PIXELMAP))
  645. #endif
  646.  
  647.     if (window->WScreen->EScreen->Map->Depth != 8)
  648.         Crash("Screen has a wrong depth - we need an 8 bit chunky pixel screen.");
  649.  
  650.     /* for faster access to this structure...*/
  651.     rp = window->RPort;
  652.  
  653.     /* now allocate memory for the image via EGS */
  654.     map = E_AllocBitMap(wwidth, wheight, 8, E_PIXELMAP, 0, 0);
  655.     if (map == NULL)
  656.         Crash("could not allocate memory for off-screen bitmap");
  657.  
  658.     /* increase lock counter on map so it doesn't get mapped away */
  659.     map->Lock++;
  660.  
  661.     /* old version...      data = map->Typekey.PixelMap.Planes.Dest; */
  662.     data = map->Plane;
  663.  
  664.     notfirst = 0;
  665.  
  666.     /* Either interpret the file while displaying it */
  667.  
  668.     if (flag_noint)
  669.     {
  670.         EI_SetWindowTitles(window, fliname, (char *)-1);
  671.         if (repeatcount)
  672.         {
  673.             while (repeatcount--)
  674.             {
  675.                 interpret_fli(fd, &header, data, notfirst, func_disp);
  676.                 notfirst = 1;
  677.             }
  678.         }
  679.         else
  680.         {
  681.             for(;;)
  682.             {
  683.                 interpret_fli(fd, &header, data, notfirst, func_disp);
  684.                 notfirst = 1;
  685.             }
  686.         }
  687.     }
  688.  
  689.     /* Or interpret everything first and display it afterwards */
  690.     else
  691.     {
  692.         text_center("Please wait while loading the animation");
  693.  
  694.         /* Interpret it and store the results */
  695.         disp_cur = &disp_root;
  696.         interpret_fli(fd, &header, data, 0, func_interp);
  697.  
  698.         /* Now display the results */
  699.         EI_SetWindowTitles(window, fliname, (char *)-1);
  700.  
  701.         if (repeatcount)
  702.         {
  703.             while (repeatcount--)
  704.             {
  705.                 disp_cur = &disp_root;
  706.                 while (disp_cur->disp_next)
  707.                 {
  708.                     disp_cur = disp_cur->disp_next;
  709.  
  710.                     /* Only display the first frame once */
  711.                     if (disp_cur->disp_frame || !notfirst)
  712.                         display_interp(disp_cur);
  713.                 }
  714.                 notfirst = 1;
  715.             }
  716.         }
  717.         else
  718.         {
  719.             for (;;)
  720.             {
  721.                 disp_cur = &disp_root;
  722.                 while (disp_cur->disp_next)
  723.                 {
  724.                     disp_cur = disp_cur->disp_next;
  725.  
  726.                     /* Only display the first frame once */
  727.                     if (disp_cur->disp_frame || !notfirst)
  728.                         display_interp(disp_cur);
  729.                 }
  730.                 notfirst = 1;
  731.             }
  732.         }
  733.     }
  734.  
  735.     Crash(NULL);
  736. }
  737.  
  738.  
  739. void Crash (char *string)
  740. {
  741.     /* free bitmaps in display list */
  742.     disp_cur = &disp_root;
  743.     while (disp_cur->disp_next)
  744.     {
  745.         disp_cur = disp_cur->disp_next;
  746.         if (disp_cur->disp_pix)
  747.         {
  748.             disp_cur->disp_pix->Lock--;
  749.             E_DisposeBitMap(disp_cur->disp_pix);
  750.         }
  751.     }
  752.  
  753.     if (window)
  754.     {
  755.         /* restore original color map (only if window was opened before) */
  756.         E_SetRGB8CM(window->WScreen->EScreen, oldscreencolors, 0, MAXCOL);
  757.     }
  758.  
  759.     if (map)
  760.     {
  761.         map->Lock--;
  762.         E_DisposeBitMap(map);
  763.     }
  764.     if (window)
  765.         EI_CloseWindow(window);
  766.  
  767.     if (screen)
  768.         EI_CloseScreen(screen);
  769.  
  770.     if (EGSBase)
  771.         CloseLibrary(EGSBase);
  772.     if (EGSBlitBase)
  773.         CloseLibrary(EGSBlitBase);
  774.     if (EGSIntuiBase)
  775.         CloseLibrary(EGSIntuiBase);
  776.     if (EGSGfxBase)
  777.         CloseLibrary(EGSGfxBase);
  778.     if (NULL == string)
  779.         exit (0);
  780.     else
  781.     {
  782.         printf ("%s.\n", string);
  783.         exit (10);
  784.     }
  785. }
  786.  
  787.